package com.sky.utils;

import com.sky.constant.JwtClaimsConstant;
import com.sky.properties.JwtProperties;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

@Component
@RequiredArgsConstructor
@Slf4j
public class JwtTool {
    
    private final JwtProperties jwtProperties;
    
    /**
     * 解析token
     *
     * @param token token
     * @return 解析token得到的用户信息
     */
    public Long parseToken(String token) {
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(jwtProperties.getAdminSecretKey().getBytes(StandardCharsets.UTF_8))
                    .parseClaimsJws(token)
                    .getBody();
            
            log.info("JWT claims: {}", claims);
            
            Object empIdObj = claims.get(JwtClaimsConstant.EMP_ID);
            if (empIdObj == null) {
                throw new RuntimeException("令牌解析失败，empId为空");
            }
            
            return Long.valueOf(empIdObj.toString());
        } catch (SignatureException e) {
            log.error("JWT签名异常: {}", e.getMessage());
            throw new RuntimeException("令牌签名无效", e);
        } catch (ExpiredJwtException e) {
            log.error("JWT token已过期: {}", e.getMessage());
            throw new RuntimeException("令牌已过期", e);
        } catch (MalformedJwtException e) {
            log.error("JWT格式错误: {}", e.getMessage());
            throw new RuntimeException("令牌格式错误", e);
        } catch (UnsupportedJwtException e) {
            log.error("不支持的JWT token: {}", e.getMessage());
            throw new RuntimeException("不支持的令牌", e);
        } catch (IllegalArgumentException e) {
            log.error("JWT claims为空: {}", e.getMessage());
            throw new RuntimeException("令牌内容为空", e);
        } catch (Exception e) {
            log.error("JWT解析异常: {}", e.getMessage());
            throw new RuntimeException("令牌解析失败", e);
        }
    }
}